package com.parkwalk.xxx.service;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.parkwalk.xxx.persistence.Mapper;
import com.parkwalk.xxx.util.SessionFactory;

/**
 * @author borball.zh@gmail.com
 * @date 2012-5-1
 * 
 */
public abstract class AbstractService<T, M> implements Service<T, M> {

	protected Class<M> mapperClazz;

	@SuppressWarnings("unchecked")
	public AbstractService() {
		this.mapperClazz = (Class<M>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
	}

	@SuppressWarnings("unchecked")
	public T findByPK(Object o) {
		SqlSession session = getSqlSession();
		try {
			return (T) getMapper(session).findByPK(o);
		} finally {
			session.close();
		}
	}

	protected SqlSession getSqlSession() {
		return SessionFactory.getInstance().getSqlSessionFactory().openSession();
	}

	@SuppressWarnings("unchecked")
	public T findByUnique(Object o) {
		SqlSession session = getSqlSession();

		try {
			return (T) getMapper(session).findByUnique(o);
		} finally {
			session.close();
		}
	}

	@SuppressWarnings("rawtypes")
	protected abstract Mapper getMapper(SqlSession session);

	@SuppressWarnings("unchecked")
	public List<T> findAll() {
		SqlSession session = getSqlSession();

		try {
			return (List<T>) getMapper(session).findAll();
		} finally {
			session.close();
		}
	}

	@SuppressWarnings("unchecked")
	public void add(T t) {
		SqlSession session = getSqlSession();

		try {
			getMapper(session).add(t);
		} finally {
			session.commit(true);
			session.close();
		}
	}

	@SuppressWarnings("unchecked")
	public void update(T t) {
		SqlSession session = getSqlSession();
		try {
			getMapper(session).update(t);
		} finally {
			session.commit(true);
			session.close();
		}
	}

	@SuppressWarnings("unchecked")
	public void delete(T t) {
		SqlSession session = getSqlSession();
		try {
			getMapper(session).delete(t);
		} finally {
			session.commit(true);
			session.close();
		}
	}

	public void deleteAll() {
		SqlSession session = getSqlSession();
		try {
			getMapper(session).deleteAll();
		} finally {
			session.commit(true);
			session.close();
		}
	}

	public void deleteByUnique(Object o) {
		SqlSession session = getSqlSession();
		try {
			getMapper(session).deleteByUnique(o);
		} finally {
			session.commit(true);
			session.close();
		}
	}

	public void deleteByPK(Object o) {
		SqlSession session = getSqlSession();
		try {
			getMapper(session).deleteByPK(o);
		} finally {
			session.commit(true);
			session.close();
		}
	}

}
